﻿using System;
using System.Collections.Generic;
using System.Text;
using log4net;

namespace Helper
{
    /// <summary>
    /// information level
    /// </summary>
    public enum Level
    {
        Debug,
        Info,
        Warn,
        Error,
        Fatal
    }

    /// <summary>
    /// log class
    /// </summary>
    public static class Log
    {
        private static object lockObj = new object();
        private static ILog logger = null;
        private static void GetLogger()
        {
            if (logger == null)
            {
                lock (lockObj)
                {
                    if (logger == null)
                    {
                        string fileFullPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");
                        System.IO.FileInfo f = new System.IO.FileInfo(fileFullPath);
                        log4net.Config.XmlConfigurator.ConfigureAndWatch(f);

                        logger = LogManager.GetLogger("MyLog");
                    }
                }
            }
        }

        static Log()
        {
            GetLogger();
        }


        public static bool IsDebugEnabled
        {
            get
            {
                if (logger != null) return logger.IsDebugEnabled;
                return false;
            }
        }

        public static bool IsInfoEnabled
        {
            get
            {
                if (logger != null) return logger.IsInfoEnabled;
                return false;
            }
        }

        public static bool IsWarnEnabled
        {
            get
            {
                if (logger != null) return logger.IsWarnEnabled;
                return false;
            }
        }

        public static bool IsErrorEnabled
        {
            get
            {
                if (logger != null) return logger.IsErrorEnabled;
                return false;
            }
        }

        public static bool IsFatalEnabled
        {
            get
            {
                if (logger != null) return logger.IsFatalEnabled;
                return false;
            }
        }

        /// <summary>
        /// log message, level is debug
        /// </summary>
        /// <param name="message"></param>
        public static void Debug(string message)
        {
            if (logger.IsDebugEnabled)
            {
                logger.Debug(message);
            }
        }

        /// <summary>
        /// log message, level is Info
        /// </summary>
        /// <param name="message"></param>
        public static void Info(string message)
        {
            if (logger.IsInfoEnabled)
            {
                logger.Info(message);
            }
        }

        /// <summary>
        /// log message, level is warn
        /// </summary>
        /// <param name="message"></param>
        public static void Warn(string message)
        {
            if (logger.IsWarnEnabled)
            {
                logger.Warn(message);
            }
        }

        /// <summary>
        /// log message, level is error
        /// </summary>
        /// <param name="message"></param>
        public static void Error(string message)
        {
            if (logger.IsErrorEnabled)
            {
                logger.Error(message);
            }
        }

        /// <summary>
        /// log message, level is error
        /// </summary>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Error(string message, Exception exception)
        {
            if (logger.IsErrorEnabled)
            {
                logger.Error(message, exception);
            }
        }

        /// <summary>
        /// log message, level is fatal
        /// </summary>
        /// <param name="message"></param>
        public static void Fatal(string message)
        {
            if (logger.IsFatalEnabled)
            {
                logger.Fatal(message);
            }
        }

        /// <summary>
        /// log message, level is fatal
        /// </summary>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Fatal(string message, Exception exception)
        {
            if (logger.IsFatalEnabled)
            {
                logger.Fatal(message, exception);
            }
        }

        /// <summary>
        /// log message with specified level
        /// </summary>
        /// <param name="message"></param>
        /// <param name="level"></param>
        public static void LogMessage(string message, Level level)
        {
            if (string.IsNullOrEmpty(message)) return;

            #region logger message
            switch (level)
            {
                case Level.Debug:
                    if (logger.IsDebugEnabled)
                    {
                        logger.Debug(message);
                    }
                    break;
                case Level.Info:
                    if (logger.IsInfoEnabled)
                    {
                        logger.Info(message);
                    }
                    break;
                case Level.Warn:
                    if (logger.IsWarnEnabled)
                    {
                        logger.Warn(message);
                    }
                    break;
                case Level.Error:
                    if (logger.IsErrorEnabled)
                    {
                        logger.Error(message);
                    }
                    break;
                case Level.Fatal:
                    if (logger.IsFatalEnabled)
                    {
                        logger.Fatal(message);
                    }
                    break;
                default:
                    break;
            }
            #endregion
        }


        /// <summary>
        /// log page request, level is info
        /// </summary>
        /// <param name="request"></param>
        [Obsolete("This method is obsolete, it has been replaced by LogRequest(System.Web.HttpRequest request, Level level)")]
        public static void LogRequest(System.Web.HttpRequest request)
        {
            LogRequest(request, Level.Info);
        }

        /// <summary>
        /// log page request with specified level
        /// </summary>
        /// <param name="request"></param>
        /// <param name="level"></param>
        public static void LogRequest(System.Web.HttpRequest request, Level level)
        {
            if (request == null) return;
            StringBuilder message = PrepareRequestInfo(request);
            LogMessage(message.ToString(), level);
        }

        private static StringBuilder PrepareRequestInfo(System.Web.HttpRequest request)
        {
            StringBuilder message = new StringBuilder();
            message.AppendFormat("==============================================================\r\n");

            message.AppendFormat("Request at {0:yyyy-MM-dd HH:mm:ss}\r\n", DateTime.Now);
            message.AppendFormat("Url:\t\t{0}\r\n", request.Url);
            message.AppendFormat("Raw Url:\t\t{0}\r\n", request.RawUrl);
            message.AppendFormat("Url Referrer:\t\t{0}\r\n", request.UrlReferrer);
            message.AppendLine();

            message.AppendLine("-------------------------------------------------------------");
            //message.AppendLine("Server Variables below:");
            //foreach (string key in request.ServerVariables.Keys)
            //{
            //    message.AppendFormat("Key:\t{0}\r\nValue:\t{1}\r\n", key, request.ServerVariables[key]);
            //}
            //message.AppendLine("-------------------------------------------------------------");
            //message.AppendLine();

            message.AppendLine("Request Query String Value below:");
            foreach (string key in request.QueryString.Keys)
            {
                message.AppendFormat("Key:\t{0}\r\nValue:\t{1}\r\n", key, System.Web.HttpUtility.UrlDecode(request.QueryString[key]));
            }
            message.AppendLine("-------------------------------------------------------------");
            message.AppendLine();

            message.AppendLine("Request Form Value below:");
            foreach (string key in request.Form.Keys)
            {
                message.AppendFormat("Key:\t{0}\r\nValue:\t{1}\r\n", key, request.Form[key]);
            }

            message.AppendLine("-------------------------------------------------------------");
            message.AppendLine();

            message.AppendLine("Cookie Value below:");
            foreach (string key in request.Cookies.Keys)
            {

                message.AppendFormat("Key:\t{0}\r\nValue:\t{1}\r\n", key,
                    System.Web.HttpUtility.UrlDecode(request.Cookies[key].Value));
            }

            message.AppendFormat("==============================================================\r\n");
            message.AppendLine();
            return message;
        }


    }
}
